package nezumi.planning;

import java.awt.Point;
import java.util.LinkedList;
import java.util.logging.Logger;

import nezumi.Constants;
import nezumi.state.State;
import nezumi.state.TargetState;

public class Planner {

	private final static LinkedList<Point> EMPTY_PATH = new LinkedList<Point>();
	protected static final Logger logger = Logger.getLogger(Planner.class
			.getName());

	private final State state;
	private int targetId = TargetState.NO_TARGET;
	private boolean goingHome = false;
	private final Point currTarget;
	private LinkedList<Point> path = EMPTY_PATH;

	public Planner(final State state, final Point currTarget) {
		assert state != null : "state = " + state;
		assert currTarget != null : "currTarget = " + currTarget;

		this.state = state;
		this.currTarget = currTarget;
	}

	public boolean isGoingHome() {
		return goingHome;
	}

	public void setGoingHome(final boolean goingHome) {
		this.goingHome = goingHome;
	}

	public Point getCurrTarget() {
		return currTarget;
	}

	public int getTargetId() {
		return this.targetId;
	}

	public void setTargetId(final int targetId) {
		assert targetId == TargetState.NO_TARGET
				|| (targetId >= 0 && targetId < Constants.N_TARGETS) : "targetId = "
				+ targetId;
		this.targetId = targetId;
	}

	public void setCurrTarget(Point newTarget) {
		assert newTarget != null : "" + newTarget;

		// only do it if they are fundamentally different
		if (currTarget.x != newTarget.x || currTarget.y != newTarget.y) {
			this.currTarget.setLocation(newTarget.getX(), newTarget.getY());
			plan();
		}
	}

	public LinkedList<Point> getPath() {
		return path;
	}

	/**
	 * Computes a new plan to the target.
	 */
	public LinkedList<Point> plan() {

		AStar planner = new AStar(state.getMapState(), state.getAgentState()
				.getCurrPosInt(), this.currTarget);

		if (!planner.findPath()) { // let us return an empty list
			this.path = EMPTY_PATH;
		} else {
			this.path = planner.getPath();
			// discard first point in path (current position)
			this.path.poll();
		}
		return this.path;
	}
}
